<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 构造函数
        // function Person(){

        // }
        
        // let person = new Person()
        // person.name = "Kevin"
        // console.log(person.name)
        // Person 就是一个构造函数，使用new创建一个实例对象person
        // prototype 每一个函数都有一个prototype属性
        // function Person(){

        // }
        // // prototype是函数才会有的属性
        // Person.prototype.name = "kevin"
        // let person1 = new Person()
        // let person2 = new Person()
        // console.log(person1.name,person2.name)
        // console.log(person1==Person.prototype)
        // 函数的prototype指向一个对象，这个对象就是构造函数而创建的实例的原型，就是person1和person2的原型
        // 什么是原型？js对象除了null之外，在创建的时候都会与之关联另一个对象，这个对象就是我们所说的原型，
        // 每一个对象都会从我们所说的原型开始继承属性
        // _proto_
        // 每一个js对象除了null之外，都具有一个属性叫_proto_,这个属性指向该对象的原型
        // 例如：
        // function Person(){

        // }
        // var person = new Person();
        // console.log(person.__proto__===Person.prototype)
        // console.log(Person.prototype.__proto__)




        // 实例对象和构造函数都可以指向原型
        // constructor
        // 一个构造函数可以生成多个实例，原型指向构造函数。
        // 每一个原型都有一个constructon属性指向关联的构造函数
        // function Person (){

        // }
        // Person.prototype.name="ooo"
        // let person = new Person()
        // console.log(Person===Person.prototype.constructor)
        // console.log(person.__proto__===Person.prototype)
        // console.log(Object.getPrototypeOf(person)===Person.prototype)
        // console.log(Person.prototype.name)
        // console.log(person.__proto__.name)
        // console.log(Object.prototype.__proto__)
        // 总结：构造函数和实例对象都指向原型，原型的constructor属性指向关联的构造函数
        // ————————————————————————————————————————————————————————————————————————
        // 实例与原型
        // 当我们读取实例属性的时候，如果找不到就会，就会查找对象关联的原型中的属性，如果还查不到，
        // 就会找原型的原型，一直找到顶层为止。
        // 例如：
        // function Person(){

        // }
        // Person.prototype.name = "kevin"
        // let person = new Person()
        // person.name = "jack"
        // delete person.name
        // console.log(person.name)//jack
        // delete person.name
        // console.log(person.name)//kevin
        // console.log(person.__proto__.name)
        // console.log(Person.prototype.name)
        // 我们访问person.name 的时候会在person的对象中查找打印jack。
        // 我们删除了person对象中的name属性，再次读取person.name对象中没有，
        // 就会向person的原型中寻找也就是person.__proto__,也就是Person.prototype中查找。
        // 万一没有找到原型的原型又是什么？？
        // ——————————————————————————————————————————————————————————————————————————————————
        // 原型的原型
        // let obj = new Object();
        // Object.prototype.name="kkk"
        // obj.name = "kevin";
        // // console.log(Object.getPrototypeOf(obj)===Object.prototype)
        // // console.log(Object.prototype.constructor===Object)

        // // console.log(Object.prototype.__proto__)

        // console.log(obj.name)
        // _________________________________________________________________________________
        // constructor
        // function Person(){

        // }
        // let person = new Person();
        // console.log(person.constructor===Person.prototype.constructor)

        // console.log(person.constructor===Person)
        // 当我们获取person.constructor属性时，person并没有constructor属性,
        // 当不能读取到constructor属性时，会从person的原型也就是Person.prototype中读取，正好原型中有该属性
        // console.log(person.constructor===Person.prototype.constructor)
        // ________________________________________________________________________________
        // __proto__
        // let obj = new Object()
        // console.log(Object.getPrototypeOf(obj))
        


        // const a;
        // 报错，常量声明必须要有初始值
        // console.log(a)


















    </script>
</body>
</html>